package com.yuerlive.rainbow.module.live.fragment;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.ImageView;

import com.pili.pldroid.player.AVOptions;
import com.pili.pldroid.player.PLMediaPlayer;
import com.pili.pldroid.player.widget.PLVideoTextureView;
import com.yuerlive.rainbow.R;
import com.yuerlive.rainbow.base.BaseFragment;
import com.yuerlive.rainbow.utils.GlideUtil;
import com.yuerlive.rainbow.utils.L;

import butterknife.BindView;

import static com.pili.pldroid.player.PLMediaPlayer.MEDIA_INFO_BUFFERING_END;
import static com.pili.pldroid.player.PLMediaPlayer.MEDIA_INFO_BUFFERING_START;
import static com.pili.pldroid.player.PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START;

/**
 * Created by xiaoyi on 2017/5/19.
 */

public class FragmentPlayVideo extends BaseFragment {
    @BindView(R.id.VideoView)
    PLVideoTextureView mVideoView;
    /*@BindView(R.id.loadingView)
    ContentLoadingProgressBar loadingView;*/
    @BindView(R.id.coverView)
    ImageView mCoverView;
    private static final int MESSAGE_ID_RECONNECTING = 0x01;
    private String mVideoPath = null;
    private int mDisplayAspectRatio = PLVideoTextureView.ASPECT_RATIO_PAVED_PARENT;

    private int mIsLiveStreaming = 1;


    @Override
    protected int getLayoutId() {
        return R.layout.fragment_playvideo;
    }


    @Override
    public void initViews(View root) {
        if (getArguments().containsKey("liveCover")) {
            String cover = getArguments().getString("liveCover");
            GlideUtil.loadBlur(mActivity, cover, mCoverView);
        }
        initVideoView();
    }

    private void initVideoView() {
//        mVideoView.setBufferingIndicator(loadingView);
//        mLoadingView.setVisibility(View.VISIBLE);
//        mCoverView = (ImageView) findViewById(R.id.CoverView);
        mVideoView.setCoverView(mCoverView);
        mVideoView.setDisplayAspectRatio(mDisplayAspectRatio);
//        mVideoPath = getIntent().getStringExtra("videoPath");

        // If you want to fix display orientation such as landscape, you can use the code show as follow
        //
        // if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        //     mVideoView.setPreviewOrientation(0);
        // }
        // else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        //     mVideoView.setPreviewOrientation(270);
        // }

//        mVideoPath = getArguments().getString("videoPath");
//        mIsLiveStreaming = getArguments().getInt("liveStreaming", 1);
//        mVideoPath = "rtmp://pili-live-rtmp.wangyuhudong.com/wyds/wyds_test_3848874";
        mVideoPath = "rtmp://pili-live-rtmp.wangyuhudong.com/wyds/wyds_4302260";
        // 1 -> hw codec enable, 0 -> disable [recommended]
//        int codec = getArguments().getInt("mediaCodec", AVOptions.MEDIA_CODEC_SW_DECODE);
        setOptions(AVOptions.MEDIA_CODEC_SW_DECODE);

        // You can mirror the display
        // mVideoView.setMirror(true);

        // You can also use a custom `MediaController` widget
        // mMediaController = new MediaController(this, false, mIsLiveStreaming==1);
        // mVideoView.setMediaController(mMediaController);

        mVideoView.setOnCompletionListener(mOnCompletionListener);
        mVideoView.setOnErrorListener(mOnErrorListener);
        mVideoView.setOnInfoListener(mOnInfoListener);

    }


    private void setOptions(int codecType) {
        AVOptions options = new AVOptions();

        // the unit of timeout is ms
        options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
        options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000);
        options.setInteger(AVOptions.KEY_PROBESIZE, 128 * 1024);
        // Some optimization with buffering mechanism when be set to 1
        options.setInteger(AVOptions.KEY_LIVE_STREAMING, mIsLiveStreaming);
        if (mIsLiveStreaming == 1) {
            options.setInteger(AVOptions.KEY_DELAY_OPTIMIZATION, 1);
        }

        // 1 -> hw codec enable, 0 -> disable [recommended]
        options.setInteger(AVOptions.KEY_MEDIACODEC, codecType);

        // whether start play automatically after prepared, default value is 1
        options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);

        mVideoView.setAVOptions(options);
    }

    @Override
    public void onDestroyView() {
        mVideoView.stopPlayback();
        mHandler.removeCallbacksAndMessages(null);
        super.onDestroyView();
    }

    @Override
    public void onPause() {
        super.onPause();
        mVideoView.pause();
    }

    @Override
    public void onResume() {
        super.onResume();

        mVideoView.start();
    }

    private PLMediaPlayer.OnErrorListener mOnErrorListener = new PLMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(PLMediaPlayer mp, int errorCode) {
            boolean isNeedReconnect = false;
            switch (errorCode) {
                case PLMediaPlayer.ERROR_CODE_INVALID_URI:
                    break;
                case PLMediaPlayer.ERROR_CODE_404_NOT_FOUND:
                    break;
                case PLMediaPlayer.ERROR_CODE_CONNECTION_REFUSED:
                    break;
                case PLMediaPlayer.ERROR_CODE_CONNECTION_TIMEOUT:
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_EMPTY_PLAYLIST:
                    break;
                case PLMediaPlayer.ERROR_CODE_STREAM_DISCONNECTED:
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_IO_ERROR:
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_UNAUTHORIZED:
                    break;
                case PLMediaPlayer.ERROR_CODE_PREPARE_TIMEOUT:
                    isNeedReconnect = true;
                    showConverView();
                    break;
                case PLMediaPlayer.ERROR_CODE_READ_FRAME_TIMEOUT:
                    isNeedReconnect = true;
                    showConverView();
                    break;
                case PLMediaPlayer.ERROR_CODE_HW_DECODE_FAILURE:
                    setOptions(AVOptions.MEDIA_CODEC_SW_DECODE);
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.MEDIA_ERROR_UNKNOWN:
                    break;
                default:
                    break;
            }
            // Todo pls handle the error status here, reconnect or call finish()
            if (isNeedReconnect) {
                sendReconnectMessage();
            } else {
                //finish();
            }
            // Return true means the error has been handled
            // If return false, then `onCompletion` will be called
            return true;
        }
    };

    private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(PLMediaPlayer plMediaPlayer) {
            showToast("hahahahhhahahahahahahh");
        }
    };

    private void sendReconnectMessage() {
//        showToast("正在重连...");
//        mCoverView.setVisibility(View.VISIBLE);
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ID_RECONNECTING), 500);
    }

    protected Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what != MESSAGE_ID_RECONNECTING) {
                return;
            }
            if (mVideoView != null) {
                mVideoView.setVideoPath(mVideoPath);
                mVideoView.start();
            }
        }
    };


    public void setVideoPath(String path) {
        this.mVideoPath = path;
        startVideo();
    }

    private void startVideo() {
        if (mVideoView == null) return;
        mVideoView.setVideoPath(mVideoPath);
        mVideoView.start();
    }

    private PLMediaPlayer.OnInfoListener mOnInfoListener = new PLMediaPlayer.OnInfoListener() {
        @Override
        public boolean onInfo(PLMediaPlayer plMediaPlayer, int what, int extra) {
            switch (what) {
                case MEDIA_INFO_VIDEO_RENDERING_START:
                    mCoverView.setVisibility(View.GONE);
                    break;
                case MEDIA_INFO_BUFFERING_END:
                    mCoverView.setVisibility(View.GONE);
                    break;
            }
            L.e(TAG, "what  " + what);
            return true;
        }
    };

    public void showConverView() {
        if (mCoverView.getVisibility() != View.VISIBLE) {
            mCoverView.setVisibility(View.VISIBLE);
            mCoverView.setImageResource(R.drawable.bg_game_niuniu);
        }
    }
}
